import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.nio.charset.Charset;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;



public class fpoutsearch {
	
	static String 	file_Import_NameTabName;
	static String 	file_Export_SearchName;
	//
	private String bookId;
	private ArrayList<String> searchList; 
	private String raw1; 
	//

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		
		fpoutsearch jcv = new fpoutsearch();
		
		String tempArgs[] = new String[args.length];
		
		for (int i = 0; i < args.length; i++) {
			tempArgs[i] = args[i].toLowerCase();
		}
		
		if (	tempArgs.length >= 4 
				&& tempArgs[0].compareTo("-f") == 0 
				&& new File(args[1]).exists() == true 
				&& tempArgs[1].contains(".out")
				&& tempArgs[2].compareTo("-b") == 0
				&& isNumeric(tempArgs[3])
				&& tempArgs[3].length() == 10) {
			//
			jcv.analyseArgs(args);
			//
			createNewFile(file_Export_SearchName);
			// 開始搜尋
			jcv.searchList = (ArrayList<String>) jcv.scanner();
			// 
			jcv.raw1 = jcv.scannerRaw1();
			// 搜尋結果寫入檔
			writeText_UTF8_Apend(jcv.raw1, file_Export_SearchName);
			writeText_UTF8_Apend(jcv.searchList, file_Export_SearchName);
			//
			System.out.println("Finish");
		}else if(tempArgs.length >= 4 && tempArgs[0].compareTo("-f") == 0 && tempArgs[1].contains(".out") && new File(args[1]).exists() == false){
			System.out.print("Error: invalid input file.\r\n");		
		}else if(tempArgs.length >= 4 && isNumeric(tempArgs[3]) && tempArgs[3].length() != 10){
			System.out.print("Error: bookid error.\r\n");		
		}else{
			System.out.print("fpoutsearch usage: java fpoutsearch -f [filename] -b [bookid]\r\n");
		}
		
	}
	
	private void analyseArgs(String[] args){
		if (args.length > 2) {
			for (int i = 2; i < args.length; i++) {
				if (args[i].compareTo("-b") == 0 ) {
					if (args.length > i+1 && isNumeric(args[i+1])) {
						bookId = args[i+1];
					}
				}
			}
		}
		file_Import_NameTabName = args[1];
		file_Export_SearchName = file_Import_NameTabName.replace(".out", "_" + bookId + ".srh") ;
	}
	
	private List<String> scanner(){
		String b_id = new StringBuffer(bookId).delete(0, 5).toString();
		ArrayList<String> searchList 	= new ArrayList<String>();
		
		try {
			Path filePath = new File(file_Import_NameTabName).toPath();
			Charset charset = Charset.defaultCharset();        
			List<String> allLines = Files.readAllLines(filePath, charset);
			//
			for (int i = 0; i < allLines.size(); i++) {
				String line = allLines.get(i);
				if (line.contains("%") == false) {
					allLines.remove(i);
					i--;
				}
				if (line.contains(b_id)) {
					StringBuffer lineStringBuffer = new StringBuffer(line);
					int num = lineStringBuffer.indexOf("{");
					lineStringBuffer.delete(0, num );
					searchList.add(lineStringBuffer.toString());
				}
			}
	        
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return searchList;
	}
	
	private String scannerRaw1(){
		// 用來放左邊資料的list
		ArrayList<Raw1> raw1List_data 	= new ArrayList<Raw1>();
		// 用來比對有沒有重複的list
		ArrayList<String> raw1List 		= new ArrayList<String>();
		// 
		String 	b_id 					= new StringBuffer(bookId).delete(0, 5).toString();
		// 搜尋後的資料
		StringBuffer raw1 				= new StringBuffer();
		
		// 先過濾左邊有才加入
		for (int i = 0; i < searchList.size(); i++) {
			String[]	array	= searchList.get(i).split("  ->  ");
			if (array[0].contains(b_id) ) {
				raw1List_data.add(new Raw1(array[1]));
			}
		}
		int count = 0;
		while (raw1List_data.size() > 0) {
			count += 1;
			for (int i = 0; i < raw1List_data.size(); i++) {
				if (raw1List_data.get(i).bookId.length == count) {
					String bookid[] = raw1List_data.get(i).bookId;
					for (int j = 0; j < bookid.length; j++) {
						String book = bookid[j];
						book = book.replace("{", "");
						book = book.replace("}", "");
						if (raw1List.size() > 0) {
							// 比對重複
							for (int k = 0; k < raw1List.size(); k++) {
								if (book.compareTo(raw1List.get(k)) != 0 && k == raw1List.size() -1) {
									raw1List.add(book);
									raw1.append(book);
									raw1.append(" ");
									break;
								}else if (book.compareTo(raw1List.get(k)) == 0) {
									break;
								}
							}
						}else{
							raw1List.add(book);
							raw1.append(book);
							raw1.append(" ");
						}
						
					}
					raw1List_data.remove(i);
					i--;
				}
			}
		}
		return raw1.toString();
	}
	
	public static boolean isNumeric(String str)
	{
		Pattern pattern = Pattern.compile("[0-9]*");
		Matcher isNum = pattern.matcher(str);
		if( !isNum.matches() )
		{
			return false;
		}
		return true;
	}
	
	private void linuxCommand(String tab, String out){
		try {
			deleteFile(out);
			Process pl = Runtime.getRuntime().exec("./fpgrowth_linux "+ tab+ " "+ out);
	        String line = "";
	        BufferedReader p_in = new BufferedReader(new InputStreamReader(pl.getInputStream()));
	        while((line = p_in.readLine()) != null){
	                System.out.println(line);
	        }
	        p_in.close();
		} catch (Exception e) {
			// TODO: handle exception
		}
		
	}
	
	private static void copyfile(String srFile, String dtFile){
		try{
			File f1 = new File(srFile);
			File f2 = new File(dtFile);
			InputStream in = new FileInputStream(f1);
		  
			//For Append the file.
		//	      OutputStream out = new FileOutputStream(f2,true);
		
			//For Overwrite the file.
			OutputStream out = new FileOutputStream(f2);
			
			byte[] buf = new byte[1024];
			int len;
			while ((len = in.read(buf)) > 0){
				out.write(buf, 0, len);
			}
			in.close();
			out.close();
	    }
	    catch(FileNotFoundException ex){
	    	System.out.println(ex.getMessage() + " in the specified directory.");
	    	System.exit(0);
	    }
	    catch(IOException e){
	    	System.out.println(e.getMessage());      
	    }
	  }
	/**
     * 建立新檔(檔案已存在會刪除舊檔並建新檔)
     * @param path
     */
    public static void createNewFile(String path){
        try{
            File file = new File(path);
            deleteFile(path);
            file.createNewFile();
        }catch(IOException e){
            e.printStackTrace();
        }
    }
    
    public static void fileReName(String path, String newName){
    	File file = new File(path);
    	file.renameTo(new File(newName));
    }
    
    /**
     * 刪檔案
     * @param path
     */
    public static void deleteFile(String path){
        File file = new File(path);
        file.delete();
    }
    
    /**
     * 寫入文字檔(使用FileWriter 寫檔編碼為預設的iso-8859-1)，
     * 因此此method使用OutputStreamWriter寫檔，可自行指定格式
     *
     * @param text        將整個String寫入指定的檔案
     * @param filename    可用相對路徑或絕對路徑
     * @param format    寫入檔案的編碼格式
     * @param append    true 將此次寫檔串在原本檔案最後面 | false 將此次寫檔蓋掉原本的文字檔內容
     * @return            true 寫檔成功 | false 寫檔失敗
     */
    public static boolean writeText(String text,String filename,String format,boolean append){
        if(text.equals("")){
            return false;
        }
        File file = new File(filename);//建立檔案，準備寫檔
        try{
            BufferedWriter bufWriter = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(file,append),format));
            bufWriter.write(text+"\n");
            bufWriter.close();
        }catch(IOException e){
            e.printStackTrace();
            System.out.println(filename + "寫檔發生錯誤");
            return false;
        }
        return true;
    }
	
    /**
     * 寫入檔案使用utf8格式寫檔，串在原本檔案內容後面
     * @param text
     * @param filename
     * @return
     */
    public static boolean writeText_UTF8_Apend(String text,String filename){
        return writeText(text, filename, "utf8", true);
    }
    // =======================================================================
    public static boolean writeText_UTF8_Apend(List<String> list,String filename){
        return writeText(list, filename, "utf8", true);
    }
    
    public static boolean writeText(List<String> list,String filename,String format,boolean append){
        if(list.size() == 0){
            return false;
        }
        File file = new File(filename);//建立檔案，準備寫檔
        try{
            BufferedWriter bufWriter = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(file,append),format));
            for (int i = 0; i < list.size(); i++) {
            	bufWriter.write(list.get(i)+"\n");
			}
            bufWriter.close();
        }catch(IOException e){
            e.printStackTrace();
            System.out.println(filename + "寫檔發生錯誤");
            return false;
        }
        return true;
    }
    
    public class Raw1 implements Comparable<Raw1>{
    	
    	public String percent;
    	public String bookId[];

    	public Raw1(String data) {
    		String[] _bookid = data.split(" ");
    		if (_bookid.length > 0) {
				percent = _bookid[_bookid.length -1].replaceAll("%", "");
				bookId = new String[_bookid.length -1];
				for (int i = 0; i < _bookid.length -1; i++) {
					bookId[i] = _bookid[i];
				}
			}
		}
    	
		@Override
		public int compareTo(Raw1 arg0) {
			// TODO Auto-generated method stub
			return this.percent.compareTo(arg0.percent);
		}
    	
    }
}
